home *** CD-ROM | disk | FTP | other *** search
Text File | 1992-02-03 | 55.1 KB | 2,107 lines |
- Newsgroups: comp.sources.x
- Path: uunet!elroy.jpl.nasa.gov!ames!pasteur!nntp
- From: scott.oaks@East.Sun.COM (Scott Oaks)
- Subject: v15i156: OpenLook Virtual Window Mgr (3.0), Part10/21
- Message-ID: <1992Feb4.135728.7486@pasteur.Berkeley.EDU>
- Sender: dcmartin@msi.com (David C. Martin - Moderator)
- Nntp-Posting-Host: postgres.berkeley.edu
- Organization: University of California, at Berkeley
- References: <csx-15i147-olvwm-3.0@uunet.UU.NET>
- Date: Tue, 4 Feb 1992 13:57:28 GMT
- Approved: dcmartin@msi.com
-
- Submitted-by: scott.oaks@East.Sun.COM (Scott Oaks)
- Posting-number: Volume 15, Issue 156
- Archive-name: olvwm-3.0/part10
-
- # This is a shell archive. Remove anything before this line, then feed it
- # into a shell via "sh file" or similar. To overwrite existing files,
- # type "sh file -c".
- # The tool that generated this appeared in the comp.sources.unix newsgroup;
- # send mail to comp-sources-unix@uunet.uu.net if you want that tool.
- # If this archive is complete, you will see the following message at the end:
- # "End of archive 10 (of 21)."
- # Contents: olwm.c states.c
- # Wrapped by dcmartin@fascet on Tue Jan 14 05:54:44 1992
- PATH=/bin:/usr/bin:/usr/ucb ; export PATH
- if test -f 'olwm.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'olwm.c'\"
- else
- echo shar: Extracting \"'olwm.c'\" \(18395 characters\)
- sed "s/^X//" >'olwm.c' <<'END_OF_FILE'
- X/*
- X * (c) Copyright 1989, 1990 Sun Microsystems, Inc. Sun design patents
- X * pending in the U.S. and foreign countries. See LEGAL_NOTICE
- X * file for terms of the license.
- X */
- X
- X#ident "@(#)olwm.c 1.1 olvwm version 1/3/92"
- X
- X/*
- X * Based on
- X#ident "@(#)olwm.c 26.42 91/09/14 SMI"
- X *
- X */
- X
- X#include <errno.h>
- X#include <memory.h>
- X#include <signal.h>
- X#include <stdio.h>
- X#include <string.h>
- X
- X#include <sys/time.h>
- X#include <sys/types.h>
- X
- X#include <sys/param.h>
- X#include <sys/resource.h>
- X#include <sys/stat.h>
- X#include <sys/wait.h>
- X
- X#include <X11/Xos.h>
- X#include <X11/Xlib.h>
- X#include <X11/Xutil.h>
- X#include <X11/Xatom.h>
- X#include <X11/Xresource.h>
- X
- X#include "i18n.h"
- X#include "ollocale.h"
- X#include "events.h"
- X#include "mem.h"
- X#include "olwm.h"
- X#include "win.h"
- X#include "menu.h"
- X#include "defaults.h"
- X#include "resources.h"
- X#include "globals.h"
- X#include "group.h"
- X#include "slots.h"
- X
- X#include "patchlevel.h"
- X
- Xtypedef void (*VoidFunc)();
- X
- X/*
- X * Globals
- X */
- Xchar *ProgramName;
- Xchar *AppName; /* strictly last component of ProgramName */
- XGlobalResourceVariables GRV;
- XXrmDatabase OlwmDB;
- X
- X
- X/*
- X * Global Quarks. "Top" refers to the root of the resource name/instance
- X * hierarchy.
- X */
- XXrmQuark TopClassQ;
- XXrmQuark TopInstanceQ;
- XXrmQuark OpenWinQ;
- X/*
- X * Quark for olwm instance -- we read resources with an instance name of
- X * olwm for backwards compatibility
- X */
- XXrmQuark OlwmQ;
- X
- X/* Current Display */
- XDisplay *DefDpy;
- X
- X
- Xstatic Display *openDisplay();
- Xstatic void parseCommandline();
- Xstatic void sendSyncSignal();
- X
- X
- X/* Note that changes to RMTable instance names must also be made here !! */
- Xstatic XrmOptionDescRec optionTable[] = {
- X { "-display", ".display",
- X XrmoptionSepArg, (caddr_t) NULL },
- X { "-f", ".setInput",
- X XrmoptionNoArg, (caddr_t) "follow" },
- X { "-follow", ".setInput",
- X XrmoptionNoArg, (caddr_t) "follow" },
- X { "-c", ".setInput",
- X XrmoptionNoArg, (caddr_t) "select" },
- X { "-click", ".setInput",
- X XrmoptionNoArg, (caddr_t) "select" },
- X { "-2d", ".use3D",
- X XrmoptionNoArg, (caddr_t) "False" },
- X { "-3d", ".use3D",
- X XrmoptionNoArg, (caddr_t) "True" },
- X { "-parent", ".reparentOK",
- X XrmoptionNoArg, (caddr_t) "False" },
- X { "-orphans", ".printOrphans",
- X XrmoptionNoArg, (caddr_t) "True" },
- X { "-all", ".printAll",
- X XrmoptionNoArg, (caddr_t) "True" },
- X { "-synchronize", ".synchronize",
- X XrmoptionNoArg, (caddr_t) "True" },
- X { "-debug", ".printOrphans", XrmoptionNoArg, (caddr_t) "True" },
- X { "-name", ".name",
- X XrmoptionSepArg, (caddr_t) NULL },
- X { "-bg", "*Background", XrmoptionSepArg, (caddr_t) NULL },
- X { "-background", "*Background", XrmoptionSepArg, (caddr_t) NULL },
- X { "-fg", "*Foreground", XrmoptionSepArg, (caddr_t) NULL },
- X { "-foreground","*Foreground", XrmoptionSepArg, (caddr_t) NULL },
- X { "-bd", "*Background",
- X XrmoptionSepArg, (caddr_t) NULL },
- X { "-bordercolor", "*Background",
- X XrmoptionSepArg, (caddr_t) NULL },
- X { "-fn", "*TitleFont", XrmoptionSepArg, (caddr_t) NULL },
- X { "-font", "*TitleFont", XrmoptionSepArg, (caddr_t) NULL },
- X { "-xrm", NULL, XrmoptionResArg, (caddr_t) NULL },
- X { "-single", ".singleScreen",XrmoptionNoArg, (caddr_t) "True" },
- X { "-multi", ".singleScreen",XrmoptionNoArg, (caddr_t) "False" },
- X { "-syncpid", ".syncPid", XrmoptionSepArg, (caddr_t) NULL },
- X { "-syncsignal",".syncSignal", XrmoptionSepArg, (caddr_t) NULL },
- X { "-depth", "*depth", XrmoptionSepArg, (caddr_t) NULL },
- X { "-visual", "*visual", XrmoptionSepArg, (caddr_t) NULL },
- X#ifdef OW_I18N_L3
- X { "-basiclocale", "*basicLocaleCL", XrmoptionSepArg, (caddr_t) NULL },
- X { "-displaylang", "*displayLangCL", XrmoptionSepArg, (caddr_t) NULL },
- X { "-inputlang", "*inputLangCL", XrmoptionSepArg, (caddr_t) NULL },
- X { "-numeric", "*numericCL", XrmoptionSepArg, (caddr_t) NULL },
- X { "-dateFormat", "*dateFormatCL", XrmoptionSepArg, (caddr_t) NULL },
- X#endif /* OW_I18N_L3 */
- X};
- X#define OPTION_TABLE_ENTRIES (sizeof(optionTable)/sizeof(XrmOptionDescRec))
- X
- Xstatic void initWinClasses();
- X
- X/* Child Process Handling */
- Xvoid HandleChildSignal();
- Xvoid ReapChildren();
- Xint DeadChildren = 0;
- Xint SlavePid;
- X
- X#ifdef ALLPLANES
- Xint allplanes; /* server supports the ALLPLANES extension */
- X#endif
- X
- X#ifdef SHAPE
- XBool ShapeSupported; /* server supports the SHAPE extension */
- Xint ShapeEventBase;
- Xint ShapeErrorBase;
- X#endif
- X
- X
- Xstatic char **argVec;
- X
- X/*
- X * main -- parse arguments, perform initialization, call event-loop
- X *
- X * The OpenLook window manager was written before the OpenLook
- X * spec. was completed. Because of this, some of it works in
- X * an awkward way. Specifically, the way a window's focus and
- X * select state is shown.
- X *
- X * For example, when a window is focused in click-to-focus mode
- X * the header gets highlighted, (black background, white text).
- X * As it was written, the titlebar window sits just inside of the
- X * resize corners. Because the OpenLook spec. requires the header to
- X * be highlighted in line with the resize corners, blacking in the
- X * the background of the titlebar window is one pixel short in each
- X * direction of being a big enough highlighted area. We can't make
- X * the titlebar bigger because it would then overlap the resize corners.
- X * Now that the spec. is complete, OLWM should be restructured.
- X *
- X * Overview:
- X *
- X * Upon startup OLWM reparents all the client windows unless
- X * the user has told it otherwise (-p option).
- X * OLWM creates a frame which will contain the client window (the pane)
- X * and the decoration windows (resize corners, titlebar). The
- X * titlebar window contains the pushpin, if any.
- X *
- X * After creating the decorations for the windows OLWM sits
- X * in a forever loop getting the next event and calling the
- X * corresponding window's event handling routine.
- X *
- X * Each window has associated with it an event handling
- X * routine (EventFrame, EventPushPin) which the main EventLoop
- X * will call when an event happens in that window. The event
- X * handling routine will call the proper routines to move a
- X * window, create a menu, etc.
- X */
- Xmain(argc, argv)
- X int argc;
- X char **argv;
- X{
- X int ErrorHandler();
- X int ExitOLWM();
- X XrmDatabase commandlineDB = NULL;
- X char *dpystr;
- X
- X#ifdef OW_I18N_L3
- X#ifndef MAXPATHLEN
- X#define MAXPATHLEN 256
- X#endif
- X char *OpenWinHome;
- X char locale_dir[MAXPATHLEN+1];
- X extern char *getenv();
- X#endif /* OW_I18N_L3 */
- X
- X#ifdef MALLOCDEBUG
- X malloc_debug(MALLOCDEBUG);
- X#endif /* MALLOCDEBUG */
- X#ifdef GPROF_HOOKS
- X moncontrol(0);
- X#endif /* GPROF_HOOKS */
- X
- X#ifdef OW_I18N_L3
- X /*
- X * Even in the SUNDAE1.0 (first release) we might need the
- X * dynamic locale change for window manager, since window
- X * manager is usually never re-start again in one sesstion.
- X * But leave static for now.
- X */
- X /*
- X * We are setting the locale (issuing the setlocale) by
- X * EffectOLLC() function, but we need to call setlocale here
- X * to handle command line argument with certain locale.
- X * FIX_ME! But may not work well, because we did not touch the
- X * Xlib function XrmParseCommand().
- X */
- X if (setlocale(LC_ALL, "") == NULL) {
- X /*
- X * FIX_ME: Following message may be misleading,
- X * because setlocale will retrieve more than just a
- X * $LANG environment variable (such as $LC_CTYPE).
- X * Also, later if the resource DB has a locale
- X * infomation, we will use it. Hence, this setting is
- X * may be only for the command line processing.
- X */
- X fprintf(stderr, gettext("\
- X olwm: Warning: '%s' is invalid locale, using 'C' locale.\n"),
- X getenv("LANG"));
- X (void)setlocale(LC_ALL,"C");
- X }
- X if ((OpenWinHome = getenv("OPENWINHOME")) != 0)
- X (void)strcpy(locale_dir,OpenWinHome);
- X else
- X (void)strcpy(locale_dir,"/usr");
- X (void)strcat(locale_dir,"/lib/locale");
- X bindtextdomain("olwm_messages",locale_dir);
- X textdomain("olwm_messages");
- X#endif /* OW_I18N_L3 */
- X
- X ProgramName = argv[0];
- X argVec = argv;
- X
- X /* Set up a signal handler so that if we are killed we put
- X * the windows back into a usable state. Specifically we
- X * need to reset the focus so they will be able to get input.
- X */
- X signal(SIGHUP, (VoidFunc)ExitOLWM);
- X signal(SIGINT, (VoidFunc)ExitOLWM);
- X signal(SIGTERM, (VoidFunc)ExitOLWM);
- X signal(SIGCHLD, HandleChildSignal);
- X
- X /* initialize the resource manager */
- X XrmInitialize();
- X
- X /* parse the command line arguments into local tmp DB */
- X parseCommandline( &argc, argv, &commandlineDB );
- X
- X DefDpy = openDisplay(commandlineDB);
- X
- X#ifdef ALLPLANES
- X {
- X int tmp;
- X allplanes = XAllPlanesQueryExtension(DefDpy, &tmp, &tmp);
- X }
- X#endif /* ALLPLANES */
- X
- X
- X#ifdef SHAPE
- X ShapeSupported = XShapeQueryExtension(DefDpy, &ShapeEventBase,
- X &ShapeErrorBase);
- X#endif /* SHAPE */
- X
- X /* put all resources into global OlwmDB and set olwm variables */
- X GetDefaults(DefDpy, commandlineDB);
- X
- X /* Initialize the event handling system. */
- X InitEvents(DefDpy);
- X InitBindings(DefDpy);
- X
- X /* Set up the error handling function. */
- X XSetErrorHandler(ErrorHandler);
- X
- X /* this can be useful for debuging strange client behaivior */
- X if (GRV.Synchronize)
- X XSynchronize(DefDpy, True);
- X
- X /* Initialize the atoms we will need to communicate with
- X * Open Look clients.
- X */
- X InitAtoms(DefDpy);
- X
- X /* Initialize the database. */
- X WIInit( DefDpy );
- X
- X /* Initialise all types of window classes */
- X initWinClasses(DefDpy);
- X
- X /* Initialize client led state */
- X InitClientState(DefDpy);
- X
- X /* initialise the group module */
- X GroupInit();
- X
- X /*
- X * Force child processes to disinherit the TCP file descriptor.
- X * This helps shell commands forked and exec'ed from menus
- X * to work properly.
- X */
- X if (fcntl(ConnectionNumber(DefDpy), F_SETFD, 1) == -1)
- X {
- X perror( gettext("olvwm: child cannot disinherit TCP fd") );
- X exit( -1 );
- X }
- X
- X#ifdef OW_I18N_L3
- X EffectOLLC(DefDpy);
- X#endif /* OW_I18N_L3 */
- X /* Init the global menus -- No more global menus; done in InitScreens
- X InitMenus(DefDpy);
- X */
- X
- X /* init region handling code */
- X InitRegions();
- X
- X /* Init screen */
- X InitScreens(DefDpy);
- X InitOlvwmRC(DefDpy);
- X GrabKeys(DefDpy, True);
- X GrabButtons(DefDpy, True);
- X ReparentScreens(DefDpy);
- X if (!GRV.FocusFollowsMouse)
- X ClientFocusTopmost(DefDpy, GetFirstScrInfo(), CurrentTime);
- X CreateAutoRootMenu(DefDpy);
- X
- X /*
- X * Start olwmslave - using the same args we got.
- X */
- X if (GRV.RunSlaveProcess)
- X SlavePid = SlaveStart(argVec);
- X
- X if (GRV.Beep != BeepNever)
- X XBell(DefDpy, 100);
- X
- X sendSyncSignal();
- X
- X EventLoop( DefDpy );
- X
- X /*NOTREACHED*/
- X}
- X
- X
- X/*
- X * parseCommandline - parse the command line arguments into a resource
- X * database
- X */
- Xstatic void
- XparseCommandline( argc, argv, tmpDB )
- Xint *argc;
- Xchar *argv[];
- XXrmDatabase *tmpDB;
- X{
- X char instName[MAX_NAME];
- X char namestr[MAX_NAME];
- X char *type, *p;
- X XrmValue val;
- X
- X /* Extract trailing pathname component of argv[0] into AppName. */
- X
- X AppName = strrchr(argv[0], '/');
- X if (AppName == NULL)
- X AppName = argv[0];
- X else
- X ++AppName;
- X
- X XrmParseCommand(tmpDB, optionTable, OPTION_TABLE_ENTRIES,
- X AppName, argc, argv );
- X
- X /*
- X * Initialize root instance and class quarks. Create the instance
- X * name by first looking up the "name" resource in the command line
- X * database (for the -name option). If it's not present, use AppName
- X * (the trailing pathname component of argv[0]). Then, scan it and
- X * replace all illegal characters with underscores. Note: we don't
- X * use the ctype functions here, because they are internationalized.
- X * In some locales, isalpha() will return true for characters that are
- X * not valid in resource component names. Thus, we must fall back to
- X * standard character comparisions.
- X *
- X * REMIND: specifying the -name option changes the name with which
- X * resources are looked up. But the command line options were put
- X * into the database using AppName, which is based on argv[0]. Thus,
- X * specifying -name causes all command-line args to be ignored, which
- X * is wrong.
- X */
- X
- X (void) strcpy(namestr, AppName);
- X (void) strcat(namestr, ".name");
- X if (XrmGetResource(*tmpDB, namestr, namestr, &type, &val)) {
- X (void) strncpy(instName, (char *)val.addr, MAX_NAME);
- X } else {
- X (void) strncpy(instName, AppName, MAX_NAME);
- X }
- X
- X instName[MAX_NAME-1] = '\0';
- X for (p=instName; *p != '\0'; ++p) {
- X if (!(*p >= 'a' && *p <= 'z' ||
- X *p >= 'A' && *p <= 'Z' ||
- X *p >= '0' && *p <= '9' ||
- X *p == '_' || *p == '-')) {
- X *p = '_';
- X }
- X }
- X TopInstanceQ = XrmStringToQuark(instName);
- X TopClassQ = XrmStringToQuark("Olwm");
- X OpenWinQ = XrmStringToQuark("OpenWindows");
- X OlwmQ = XrmStringToQuark("olwm");
- X
- X /* check to see if there are any arguments left unparsed */
- X if ( *argc != 1 )
- X {
- X /* check to see if it's -help */
- X if ( argv[1][0] == '-' && argv[1][1] == 'h' )
- X usage(gettext("Command line arguments accepted"),gettext("are:"));
- X else
- X usage(gettext("Unknown argument(s)"), gettext("encountered"));
- X }
- X}
- X
- X
- X/*
- X * openDisplay
- X */
- Xstatic Display *
- XopenDisplay(rdb)
- X XrmDatabase rdb;
- X{
- X char namebuf[MAX_NAME];
- X char *type;
- X XrmValue value;
- X char *dpystr = NULL;
- X char *envstr;
- X Display *dpy;
- X
- X (void) strcpy(namebuf, AppName);
- X (void) strcat(namebuf, ".display");
- X
- X if (XrmGetResource(rdb, namebuf, namebuf, &type, &value)) {
- X dpystr = (char *)value.addr;
- X envstr = (char *)MemAlloc(8+strlen(dpystr)+1);
- X sprintf(envstr, "DISPLAY=%s", dpystr);
- X putenv(envstr);
- X }
- X
- X dpy = XOpenDisplay(dpystr);
- X if (dpy == NULL) {
- X fprintf(stderr, gettext("%s: cannot connect to %s\n"),
- X ProgramName, dpystr);
- X exit(1);
- X }
- X return dpy;
- X}
- X
- X
- X/*
- X * sendSyncSignal
- X *
- X * Send a signal to the process named on the command line (if any). Values
- X * for the process id and signal to send are looked up in the resource
- X * database; they are settable with command-line options. The resources are
- X * looked up with the names
- X *
- X * <appname>.syncPid process id
- X * <appname>.syncSignal signal to send (integer)
- X *
- X * where <appname> is the trailing pathname component of argv[0].
- X */
- Xstatic void
- XsendSyncSignal()
- X{
- X char *type;
- X XrmValue value;
- X int pid;
- X int sig = SIGALRM;
- X int tmp;
- X char namebuf[100];
- X
- X (void) strcpy(namebuf, AppName);
- X (void) strcat(namebuf, ".syncPid");
- X if (!XrmGetResource(OlwmDB, namebuf, namebuf, &type, &value))
- X return;
- X pid = atoi((char *)value.addr);
- X if (pid <= 0 || pid > MAXPID)
- X return;
- X
- X (void) strcpy(namebuf, AppName);
- X (void) strcat(namebuf, ".syncSignal");
- X if (XrmGetResource(OlwmDB, namebuf, namebuf, &type, &value)) {
- X tmp = atoi((char *)value.addr);
- X if (tmp > 0 && tmp <= SIGUSR2)
- X sig = tmp;
- X }
- X (void) kill(pid, sig);
- X}
- X
- X
- Xstatic void
- XinitWinClasses(dpy)
- XDisplay *dpy;
- X{
- X FrameInit(dpy);
- X IconInit(dpy);
- X ResizeInit(dpy);
- X ColormapInit(dpy);
- X ButtonInit(dpy);
- X BusyInit(dpy);
- X MenuInit(dpy);
- X PinMenuInit(dpy);
- X RootInit(dpy);
- X NoFocusInit(dpy);
- X PushPinInit(dpy);
- X PaneInit(dpy);
- X IconPaneInit(dpy);
- X VirtualInit(dpy);
- X}
- X
- X
- X/*
- X * Exit -- exit routine called by menus.
- X * Kill all running applications.
- X */
- XExit(dpy)
- XDisplay *dpy;
- X{
- X extern void *ClientShutdown();
- X
- X SlaveStop();
- X ListApply(ActiveClientList, ClientShutdown, (void *)0);
- X XSync(dpy, True);
- X exit(0);
- X /*NOTREACHED*/
- X}
- X
- X
- Xstatic void
- Xcleanup()
- X{
- X extern void *UnparentClient();
- X
- X /*
- X * If DefDpy is NULL then we didn't get to the XOpenDisplay()
- X * so basically there is nothing to clean up so return.
- X */
- X if (DefDpy == NULL)
- X return;
- X
- X /*
- X * Stop olwmslave
- X */
- X SlaveStop();
- X
- X /*
- X * destroy all pinned menus
- X */
- X DestroyPinnedMenuClients();
- X
- X /*
- X * Clean up the virtual desktop -- if we aren't left in the upper
- X * left corner, nothing will start in the right place
- X */
- X VirtualCleanup(DefDpy);
- X
- X /*
- X * Go through the list of windows. Unmap all icons that are on the
- X * screen. Reparent all windows back to the root, suitably offset
- X * according to their window-gravities. Also remap all non-withdrawn
- X * windows, and remove all Withdrawn windows from the save-set (so
- X * they don't get remapped. REMIND: We have to do this because
- X * Withdrawn windows are still left reparented inside the frame; this
- X * shouldn't be the case.
- X */
- X ListApply(ActiveClientList,UnparentClient,NULL);
- X
- X /* Destroy the screens - which will restore input focus, colormap,
- X * and background, etc.
- X */
- X DestroyScreens(DefDpy);
- X
- X XSync(DefDpy, True);
- X}
- X
- X
- X/* Clean up and then re-exec argv. */
- Xint
- XRestartOLWM()
- X{
- X cleanup();
- X execvp(argVec[0], argVec);
- X ErrorGeneral("cannot restart");
- X /*NOTREACHED*/
- X}
- X
- X
- X/* Clean up and then exit. */
- Xint
- XExitOLWM()
- X{
- X cleanup();
- X exit(0);
- X}
- X
- X
- X/*
- X * HandleChildSignal - keep track of children that have died
- X */
- Xstatic void
- XHandleChildSignal()
- X{
- X /*
- X * Following is only neede for SYSV but it doesn't hurt in BSD
- X */
- X signal(SIGCHLD, HandleChildSignal);
- X ++DeadChildren;
- X}
- X
- X/*
- X * ReapChildren - wait() for all dead child processes
- X */
- Xvoid
- XReapChildren()
- X{
- X#ifdef SYSV
- X sigset_t newmask, oldmask;
- X int status;
- X pid_t pid;
- X#else
- X int oldmask;
- X int pid;
- X union wait status;
- X#endif
- X
- X#ifdef SYSV
- X sigemptyset(&newmask);
- X sigemptyset(&oldmask);
- X sigaddset(&newmask, SIGCHLD);
- X sigprocmask(SIG_BLOCK, &newmask, &oldmask);
- X#else
- X oldmask = sigblock(sigmask(SIGCHLD));
- X#endif
- X while (DeadChildren>0)
- X {
- X#ifdef SYSV
- X pid = waitpid(-1, &status, WNOHANG);
- X#else
- X pid = wait3(&status, WNOHANG, (struct rusage *)0);
- X#endif
- X /* if it's the slave process then stop its use */
- X if (pid == SlavePid)
- X SlaveStopped();
- X
- X if (pid == 0)
- X {
- X /* Removed error message - deemed not useful */
- X DeadChildren = 0;
- X break;
- X }
- X if (WIFSTOPPED(status))
- X {
- X kill(pid, SIGKILL);
- X }
- X --DeadChildren;
- X }
- X#ifdef SYSV
- X sigprocmask(SIG_SETMASK, &oldmask, &oldmask);
- X#else
- X (void) sigsetmask(oldmask);
- X#endif
- X}
- X
- X/*
- X * usage(s1, s2) -- print informative message regarding usage
- X */
- Xstatic
- Xusage(s1, s2)
- Xchar *s1, *s2;
- X{
- X fprintf(stderr, "%s %s\n", s1, s2);
- X fprintf(stderr,
- X "usage: %s [-2d] [-3d] [-click] [-follow] [-parent]\n", ProgramName);
- X fputs(
- X /* STRING_EXTRACTION - do not translate "-display" ,"-name"
- X * and "-xrm", becuase those are namne of command line option.
- X */
- X gettext("\t[-display <display>] [-name <classname>] [-xrm <rsrcstring>]\n"),
- X stderr);
- X fputs("\t[-all] [-debug] [-orphans] [-synchronize] [-single]\n", stderr);
- X fputs("\t[-syncpid pid] [-syncsignal signal]\n", stderr);
- X exit(1);
- X}
- X
- END_OF_FILE
- if test 18395 -ne `wc -c <'olwm.c'`; then
- echo shar: \"'olwm.c'\" unpacked with wrong size!
- fi
- # end of 'olwm.c'
- fi
- if test -f 'states.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'states.c'\"
- else
- echo shar: Extracting \"'states.c'\" \(33415 characters\)
- sed "s/^X//" >'states.c' <<'END_OF_FILE'
- X/* (c) Copyright 1989, 1990 Sun Microsystems, Inc. Sun design patents
- X * pending in the U.S. and foreign countries. See LEGAL_NOTICE
- X * file for terms of the license.
- X */
- X
- X/* states.c - functions relating to changes in client state
- X * (Normal, Iconic, Withdrawn)
- X */
- X
- X#ident "@(#)states.c 1.1 olvwm version 1/3/92"
- X
- X/*
- X * Based on
- X#ident "@(#)states.c 26.50 91/09/14 SMI"
- X *
- X */
- X
- X#include <errno.h>
- X#include <stdio.h>
- X#include <X11/Xos.h>
- X#include <X11/Xlib.h>
- X#include <X11/Xutil.h>
- X#include <X11/Xatom.h>
- X
- X#include "i18n.h"
- X#include "ollocale.h"
- X#include "mem.h"
- X#include "olwm.h"
- X#include "win.h"
- X#include "group.h"
- X#include "globals.h"
- X#include "properties.h"
- X#include "virtual.h"
- X
- X/***************************************************************************
- X* global data
- X***************************************************************************/
- X
- Xextern Atom AtomWMClass;
- Xextern Atom AtomDecorAdd;
- Xextern Atom AtomDecorClose;
- Xextern Atom AtomDecorDel;
- Xextern Atom AtomDecorFooter;
- Xextern Atom AtomDecorHeader;
- Xextern Atom AtomDecorIconName;
- Xextern Atom AtomDecorPin;
- Xextern Atom AtomDecorResize;
- Xextern Atom AtomDeleteWindow;
- Xextern Atom AtomMenuFull;
- Xextern Atom AtomMenuLimited;
- Xextern Atom AtomNone;
- Xextern Atom AtomOlwmTimestamp;
- Xextern Atom AtomPinIn;
- Xextern Atom AtomPinOut;
- Xextern Atom AtomProtocols;
- Xextern Atom AtomSaveYourself;
- Xextern Atom AtomTakeFocus;
- Xextern Atom AtomWinAttr;
- Xextern Atom AtomWTBase;
- Xextern Atom AtomWTCmd;
- Xextern Atom AtomWTHelp;
- Xextern Atom AtomWTNotice;
- Xextern Atom AtomWTOther;
- X
- Xextern Client *CurrentClient;
- X
- Xextern int WinDrawFunc();
- Xextern void IconPaneSetPixmap();
- Xextern void IconPaneSetMask();
- X
- X/***************************************************************************
- X* private data
- X***************************************************************************/
- X
- X/* sanity checks for getting stuff out of hints */
- X#define IsCard16(x) ((x) == ((unsigned short)(x)) && (x) > 0 )
- X#define IsInt16(x) ((x) == ((short) (x)))
- X
- Xstatic WMDecorations BaseWindow = {
- X WMDecorationCloseButton | WMDecorationResizeable | WMDecorationHeader
- X | WMDecorationIconName,
- X MENU_FULL,
- X 0,
- X PIN_IN,
- X 0
- X};
- X
- Xstatic WMDecorations CmdWindow = {
- X WMDecorationPushPin | WMDecorationResizeable | WMDecorationHeader
- X | WMDecorationIconName,
- X MENU_LIMITED,
- X 0,
- X PIN_IN,
- X 0
- X};
- X
- Xstatic WMDecorations NoticeWindow = {
- X WMDecorationIconName,
- X MENU_NONE,
- X 0,
- X PIN_IN,
- X 0
- X};
- X
- Xstatic WMDecorations HelpWindow = {
- X WMDecorationPushPin | WMDecorationHeader | WMDecorationIconName
- X | WMDecorationWarpToPin,
- X MENU_LIMITED,
- X 0,
- X PIN_IN,
- X 0
- X};
- X
- Xstatic WMDecorations OtherWindow = {
- X WMDecorationIconName,
- X MENU_NONE,
- X 0,
- X PIN_IN,
- X 0
- X};
- X
- Xstatic WMDecorations TransientWindow = {
- X WMDecorationResizeable | WMDecorationIconName,
- X MENU_LIMITED,
- X 0,
- X PIN_IN,
- X 0
- X};
- X
- Xstatic WMDecorations MinimalWindow = {
- X WMDecorationResizeable | WMDecorationIconName,
- X MENU_FULL,
- X 0,
- X PIN_IN,
- X 0
- X};
- X
- Xstatic WMDecorations NoDecors = {
- X WMNoDecor,
- X MENU_NONE,
- X 0,
- X PIN_OUT,
- X 0
- X};
- X
- Xtypedef struct {
- X char *class, *instance, *name;
- X} minimalclosure;
- X
- X
- X/***************************************************************************
- X* private functions
- X***************************************************************************/
- X
- X/*
- X * Determine FocusMode from wmHints and protocols
- X */
- Xstatic FocusMode
- XfocusModeFromHintsProtocols(wmHints,protocols)
- X XWMHints *wmHints;
- X int protocols;
- X{
- X FocusMode focusMode;
- X
- X if (wmHints && wmHints->input) {
- X if (protocols & TAKE_FOCUS)
- X focusMode = LocallyActive;
- X else
- X focusMode = Passive;
- X } else { /* wmHints->input == False */
- X if (protocols & TAKE_FOCUS)
- X focusMode = GloballyActive;
- X else
- X focusMode = NoInput;
- X }
- X return focusMode;
- X}
- X
- X/* matchInstClass -- run through the list of names to be minimally
- X * decorated, and see if this window's class or instance match
- X * any.
- X *
- X * In olvwm, we check the name as well as class/instance
- X */
- Xstatic Bool
- XmatchInstClass(str,mc)
- Xchar *str;
- Xminimalclosure *mc;
- X{
- X if ((mc->class != NULL) && (!strcmp(str, mc->class)))
- X return True;
- X if ((mc->instance != NULL) && (!strcmp(str, mc->instance)))
- X return True;
- X if ((mc->name != NULL) && (!strncmp(str, mc->name, strlen(str))))
- X return True;
- X return False;
- X}
- X
- X
- X/*
- X * getOlWinDecors - given the window attributes and decoration add/delete
- X * requests, determine what kind of window (according to the OpenLook
- X * kinds of windows) the client represents, and determine what sort of
- X * decorations are appropriate.
- X */
- XWMDecorations *
- XgetOLWinDecors(dpy, win, transient, cli)
- XDisplay *dpy;
- XWindow win;
- XBool transient;
- XClient *cli;
- X{
- X WMDecorations *decors;
- X minimalclosure mc;
- X XWMHints *wmHints = cli->wmHints;
- X OLWinAttr *winAttrs;
- X Bool oldVersion;
- X int decorFlags;
- X
- X decors = MemNew(WMDecorations);
- X
- X /*
- X * REMIND: there is no way for a program to
- X * specify the default item, even if it should
- X * specify the menu
- X * so this get's initialized here
- X * (one per window)
- X */
- X decors->def_item = 0;
- X
- X /* if the instance or class strings match any of the names
- X * listed for minimal decoration, only provide resize corners
- X * and a menu.
- X */
- X mc.class = cli->wmClass;
- X mc.instance = cli->wmInstance;
- X if (!XFetchName(dpy, win, &mc.name))
- X mc.name = NULL;
- X if (ListApply(GRV.Minimals,matchInstClass,&mc) != NULL)
- X {
- X *decors = MinimalWindow;
- X return decors;
- X }
- X if (ListApply(GRV.NoDecors, matchInstClass, &mc) != NULL) {
- X *decors = NoDecors;
- X if (mc.name)
- X XFree(mc.name);
- X return decors;
- X }
- X if (mc.name)
- X XFree(mc.name);
- X
- X#ifdef SHAPE
- X if (cli->isShaped) {
- X *decors = MinimalWindow;
- X return decors;
- X }
- X#endif
- X
- X oldVersion = False;
- X winAttrs = MemNew(OLWinAttr);
- X
- X /*
- X * If the _OL_WIN_ATTR property is not present then make the
- X * window into a base window unless is a transient window.
- X */
- X if (!PropGetOLWinAttr(dpy,win,winAttrs,&oldVersion)) {
- X if (transient) {
- X *decors = TransientWindow;
- X if (GRV.TransientsTitled)
- X decors->flags |= WMDecorationHeader;
- X } else {
- X *decors = BaseWindow;
- X }
- X /*
- X * Else we do have that property; so interpret it
- X */
- X } else {
- X /*
- X * Choose the decor from win_type
- X */
- X if ((winAttrs->flags & WA_WINTYPE) == 0) {
- X *decors = BaseWindow;
- X } else if (winAttrs->win_type == AtomWTBase) {
- X *decors = BaseWindow;
- X } else if (winAttrs->win_type == AtomWTCmd) {
- X *decors = CmdWindow;
- X } else if (winAttrs->win_type == AtomWTHelp) {
- X *decors = HelpWindow;
- X } else if (winAttrs->win_type == AtomWTNotice) {
- X *decors = NoticeWindow;
- X } else if (winAttrs->win_type == AtomWTOther) {
- X *decors = OtherWindow;
- X
- X /*
- X * This is the only case where we look at menu type
- X */
- X if (winAttrs->flags & WA_MENUTYPE) {
- X if (winAttrs->menu_type == AtomMenuFull)
- X decors->menu_type = MENU_FULL;
- X else if (winAttrs->menu_type == AtomMenuLimited)
- X decors->menu_type = MENU_LIMITED;
- X else if (winAttrs->menu_type == AtomNone)
- X decors->menu_type = MENU_NONE;
- X }
- X }
- X
- X /*
- X * Backward compatibility. If we had a old/short attribute
- X * property, and the client specified an icon window, we're
- X * probably dealing with an old XView client. These clients
- X * assume the window manager doesn't put the icon name in
- X * the icon, so they paint it into the icon window itself.
- X * Turn off the painting of the icon name for icons of
- X * these windows.
- X */
- X if (oldVersion && wmHints && (wmHints->flags & IconWindowHint))
- X decors->flags &= ~WMDecorationIconName;
- X
- X /*
- X * Set cancel if something specified
- X */
- X if (winAttrs->flags & WA_CANCEL)
- X decors->cancel = (winAttrs->cancel != 0);
- X
- X /*
- X * Set the pin state
- X */
- X if (winAttrs->flags & WA_PINSTATE) {
- X decors->pushpin_initial_state =
- X winAttrs->pin_initial_state;
- X } else {
- X decors->pushpin_initial_state = PIN_OUT;
- X }
- X }
- X
- X /*
- X * Apply DecorAdd flags
- X */
- X if (PropGetOLDecorAdd(dpy,win,&decorFlags)) {
- X decors->flags |= decorFlags;
- X }
- X
- X /*
- X * Apply DecorDel flags
- X */
- X if (PropGetOLDecorDel(dpy,win,&decorFlags)) {
- X decors->flags &= ~decorFlags;
- X }
- X
- X /*
- X * If the window has no header it can't have any header
- X * decorations; ie. pushpin or a close button.
- X */
- X if (!(decors->flags & WMDecorationHeader)) {
- X decors->flags &= ~(WMDecorationHeaderDeco);
- X }
- X
- X /*
- X * If the window wants both a pushpin and a close button it
- X * only can have a pushpin.
- X */
- X if ((decors->flags & WMDecorationCloseButton) &&
- X (decors->flags & WMDecorationPushPin))
- X decors->flags &= ~(WMDecorationCloseButton);
- X
- X /*
- X * Don't warp to the pin if there's no pin.
- X */
- X if (!(decors->flags & WMDecorationPushPin))
- X decors->flags &= ~WMDecorationWarpToPin;
- X
- X return decors;
- X}
- X
- X
- X/*
- X * calcPosition
- X *
- X * Calculate the next position to place a new window. This function places
- X * all new windows on the diagonal and makes sure that there is enough room on
- X * the screen for the new window's size passed in w and h.
- X */
- Xstatic void
- XcalcPosition(dpy, screen, attrs, frame)
- X Display *dpy;
- X int screen;
- X XWindowAttributes *attrs;
- X WinPaneFrame *frame;
- X{
- X int stepValue;
- X ScreenInfo *scrInfo;
- X
- X if ((scrInfo = GetScrInfoOfScreen(screen)) == NULL) {
- X attrs->x = attrs->y = 0;
- X return;
- X }
- X
- X /* if the height of the current window is too large ... */
- X if ((scrInfo->framepos + frame->core.height
- X > DisplayHeight(dpy, screen)) ||
- X (scrInfo->framepos + frame->core.width
- X > DisplayWidth(dpy, screen)))
- X {
- X scrInfo->framepos = 0;
- X }
- X
- X /* REMIND this should really be based on the header height */
- X stepValue = 30;
- X
- X /* we will return the current position */
- X attrs->x = attrs->y = scrInfo->framepos;
- X
- X /* calculate the next return value */
- X scrInfo->framepos = scrInfo->framepos + stepValue;
- X if ((scrInfo->framepos > DisplayWidth(dpy, screen)) ||
- X (scrInfo->framepos > DisplayHeight(dpy, screen)))
- X {
- X scrInfo->framepos = 0;
- X }
- X}
- X
- X
- X/*
- X * iconifyOne -- iconify one client
- X */
- Xstatic void *
- XiconifyOne(cli, winIcon)
- XClient *cli;
- XWinGeneric *winIcon;
- X{
- X if (cli->groupmask == GROUP_DEPENDENT)
- X RemoveSelection(cli); /* warp if necessary */
- X else
- X DrawIconToWindowLines(cli->dpy, winIcon, cli->framewin);
- X
- X UnmapWindow(cli->framewin);
- X XUnmapWindow(cli->dpy, PANEWINOFCLIENT(cli));
- X cli->framewin->fcore.panewin->pcore.pendingUnmaps++;
- X cli->wmState = IconicState;
- X ClientSetWMState(cli);
- X return NULL;
- X}
- X
- X/* deiconifyOne -- deiconify one client
- X */
- Xstatic void *
- XdeiconifyOne(cli, winIcon, raise)
- XClient *cli;
- XWinGeneric *winIcon;
- XBool raise;
- X{
- X if (cli->groupmask != GROUP_DEPENDENT)
- X DrawIconToWindowLines(cli->dpy, winIcon, cli->framewin);
- X
- X if (raise)
- X RaiseWindow(cli->framewin);
- X
- X MapWindow(cli->framewin);
- X XMapRaised(cli->dpy, PANEWINOFCLIENT(cli));
- X cli->wmState = NormalState;
- X ClientSetWMState(cli);
- X return NULL;
- X}
- X
- X
- X/*
- X * markFrame
- X *
- X * Marks a client's frame window with a given value. Suitable for calling by
- X * ListApply or GroupApply.
- X */
- Xstatic void *
- XmarkFrame(cli, value)
- X Client *cli;
- X int value;
- X{
- X if (cli->framewin != NULL)
- X cli->framewin->core.tag = value;
- X return NULL;
- X}
- X
- X
- X/*
- X * deiconifyGroup
- X *
- X * Deiconify a window group, preserving stacking order. Mark all the frames
- X * that are to be deiconified, then query the server for all children-of-root.
- X * Walk backward through this array (i.e. from top to bottom). For each group
- X * member found, stack it just below the previous one (raise the first one to
- X * the top) and deiconify it. Finally, unmark all the frames in the group.
- X * Note: this algorithm depends on having the stacking order of windows
- X * preserved when the group is iconified.
- X */
- Xstatic void
- XdeiconifyGroup(cli, winIcon)
- X Client *cli;
- X WinIconFrame* winIcon;
- X{
- X Window root, parent;
- X Window *children;
- X Window prev = None;
- X unsigned int nchildren;
- X int i;
- X WinGeneric *wi;
- X XWindowChanges xwc;
- X
- X GroupApply(cli->groupid, markFrame, 1, GROUP_LEADER|GROUP_DEPENDENT);
- X
- X (void) XQueryTree(cli->dpy, cli->scrInfo->rootid, &root, &parent,
- X &children, &nchildren);
- X
- X xwc.stack_mode = Below;
- X for (i=nchildren-1; i>=0; --i) {
- X wi = WIGetInfo(children[i]);
- X if (wi != NULL && wi->core.tag == 1) {
- X if (prev == None) {
- X RaiseWindow(wi);
- X } else {
- X xwc.sibling = prev;
- X ConfigureWindow(cli->dpy, wi,
- X CWSibling|CWStackMode, &xwc);
- X }
- X prev = children[i];
- X deiconifyOne(wi->core.client, winIcon, False);
- X }
- X }
- X
- X if (children != NULL)
- X XFree((char *)children);
- X
- X GroupApply(cli->groupid, markFrame, 0, GROUP_LEADER|GROUP_DEPENDENT);
- X}
- X
- X
- X/***************************************************************************
- X* global functions
- X***************************************************************************/
- X
- X
- X/*
- X * StateNew -- A client is mapping a top-level window (either a new window
- X * or a Withdrawn window). The window may become Iconic or Normal
- X * depending on the hints. Check to see if this window needs to be mapped
- X * and if so add the required adornments.
- X * dpy -- display pointer
- X * rootWin -- root window
- X * if None will determine the root window
- X * for the client window
- X * window -- client's window
- X * fexisting -- the window already exists and we
- X * are starting olwm, so positioning should
- X * be special-cased
- X * ourWinInfo -- if is this one of our menu windows, this
- X * will be its WinMenu structure; this window must
- X * be a subclass of Pane
- X * If this is a VDM, this will be a subclass of
- X * VPane
- X */
- XClient *
- XStateNew(dpy, rootWin, window, fexisting, ourWinInfo)
- XDisplay *dpy;
- XWindow rootWin;
- XWindow window;
- XBool fexisting;
- XWinPane *ourWinInfo;
- X{
- X Client *cli;
- X WinGeneric *winGeneric;
- X WinPane *winPane;
- X WinIconFrame *winIcon;
- X WinPaneFrame *winFrame;
- X WinIconPane *winIconPane;
- X XSizeHints *normHints;
- X Bool preICCCM;
- X Bool transient = False;
- X int status;
- X int initstate;
- X XWindowAttributes paneAttr;
- X int screen;
- X int tmpx, tmpy;
- X ScreenInfo *scrInfo;
- X int winState;
- X Window iconWin;
- X minimalclosure mc;
- X int icon_x, icon_y;
- X
- X /*
- X * If the window is thought to be new (i.e. if ourWinInfo is null, as
- X * it is always except for the case of pinned menus and the VDM) and
- X * the window * has already been registered in the WinInfo database
- X * and it's anything other than colormap window, then return.
- X *
- X * This is to head off (a) clients that might be mapping the olwm
- X * frame, (b) clients that map their top-level window (pane) more than
- X * once before olwm can reparent it to a frame, and (c) olwm's own
- X * popup menus.
- X */
- X if (!ourWinInfo &&
- X (winGeneric = WIGetInfo(window)) != NULL &&
- X winGeneric->core.kind != WIN_COLORMAP) {
- X return NULL;
- X }
- X
- X /* Find the screen the client window is on.
- X * If ourWinInfo is valid, use it's screen
- X * Else if know the root then use it's screen
- X * Lastly QueryTree to find out from the server
- X */
- X if (ourWinInfo) {
- X screen = ourWinInfo->core.client->scrInfo->screen;
- X } else if (rootWin != None) {
- X if ((scrInfo = GetScrInfoOfRoot(rootWin)) == NULL)
- X return NULL;
- X screen = scrInfo->screen;
- X } else {
- X Window root, parent, *children;
- X unsigned int nChild;
- X Status result;
- X
- X result = XQueryTree(dpy, window, &root, &parent,
- X &children, &nChild);
- X
- X if (result == 0 || parent != root)
- X return NULL;
- X if ((scrInfo = GetScrInfoOfRoot(root)) == NULL)
- X return NULL;
- X screen = scrInfo->screen;
- X }
- X
- X /*
- X * Select for events on the pane right now (including StructureNotify)
- X * so that we are guaranteed to get a DestroyNotify if the window goes
- X * away. If the window has already gone away, the call to
- X * XGetWindowAttributes below will tell us without race conditions.
- X */
- X if (!ourWinInfo)
- X XSelectInput(dpy, window,
- X PropertyChangeMask | StructureNotifyMask |
- X ColormapChangeMask | EnterWindowMask);
- X
- X /* get all the info about the new pane */
- X status = XGetWindowAttributes(dpy, window, &paneAttr);
- X if ( status == 0 ) {
- X return NULL;
- X }
- X
- X /*
- X * If it's an override-redirect window, or if already exists but is
- X * unmapped, ignore it after first removing our StructureNotify
- X * interest.
- X */
- X if (paneAttr.override_redirect ||
- X (fexisting && paneAttr.map_state != IsViewable)) {
- X if (!ourWinInfo)
- X XSelectInput(dpy, window, NoEventMask);
- X return NULL;
- X }
- X
- X /* Create the client structure so we can start hooking things to it */
- X if ((cli = ClientCreate(dpy,screen)) == NULL)
- X {
- X return NULL;
- X }
- X
- X#ifdef SHAPE
- X {
- X Bool bshaped, cshaped;
- X int bx, by, cx, cy;
- X unsigned int bw, bh, cw, ch;
- X
- X if (ShapeSupported &&
- X 0 != XShapeQueryExtents(dpy, window, &bshaped, &bx, &by,
- X &bw, &bh, &cshaped, &cx, &cy,
- X &cw, &ch))
- X {
- X XShapeSelectInput(dpy, window, ShapeNotifyMask);
- X cli->isShaped = bshaped;
- X } else {
- X cli->isShaped = False;
- X }
- X }
- X#endif /* SHAPE */
- X
- X /*
- X * Turn on prop read filtering with set of available properties
- X */
- X PropSetAvailable(dpy,window);
- X
- X /*
- X * Get the WM_TRANSIENT_FOR hint. If the property exists but has a
- X * contents of zero, or the window itself, substitute the root's
- X * window ID. This is because some (buggy) clients actually write
- X * zero in the WM_TRANSIENT_FOR property, and we want to give them
- X * transient window behavior.
- X */
- X if (!PropGetWMTransientFor(dpy,window,cli->scrInfo->rootid,
- X &(cli->transientFor))) {
- X cli->transientFor = 0;
- X transient = False;
- X } else {
- X transient = True;
- X }
- X
- X /*
- X * Get the WM_NORMAL_HINTS property. If it's short, then we have a
- X * pre-ICCCM client on our hands, so we interpret some values
- X * specially.
- X */
- X normHints = MemNew(XSizeHints);
- X
- X if (!PropGetWMNormalHints(dpy,window,normHints,&preICCCM)) {
- X normHints->win_gravity = NorthWestGravity;
- X normHints->flags = PWinGravity;
- X }
- X
- X /*
- X * We got a short property. Assume that this is a pre-X11R4
- X * client who's using the short version of the property. Copy
- X * the data into a correctly-sized structure. Then, depending
- X * on the flags set, ignore the window's real geometry and use
- X * the data in the hint (but only if it passes some sanity
- X * checking). The sanity checking is necessary because early
- X * versions of XView write a short property, but rely on the
- X * window manager to look at the window's geometry instead of
- X * at the values in the hint.
- X */
- X if (preICCCM) {
- X int maxDpyWidth = 2*DisplayWidth(dpy,screen);
- X int maxDpyHeight = 2*DisplayHeight(dpy,screen);
- X
- X if (!fexisting
- X && (normHints->flags & (USPosition|PPosition))
- X && IsInt16(normHints->x)
- X && IsInt16(normHints->y)
- X && normHints->x > -maxDpyWidth
- X && normHints->y > -maxDpyHeight
- X && normHints->x < maxDpyWidth
- X && normHints->y < maxDpyHeight) {
- X paneAttr.x = normHints->x;
- X paneAttr.y = normHints->y;
- X }
- X if ((normHints->flags & (USSize|PSize))
- X && IsCard16(normHints->width)
- X && IsCard16(normHints->height)
- X && normHints->width >= MINSIZE
- X && normHints->height >= MINSIZE
- X && normHints->width < maxDpyWidth
- X && normHints->height < maxDpyHeight) {
- X paneAttr.width = normHints->width;
- X paneAttr.height = normHints->height;
- X }
- X }
- X
- X cli->normHints = normHints;
- X
- X /*
- X * Get the WM_HINTS
- X */
- X cli->wmHints = MemNew(XWMHints);
- X
- X if (!PropGetWMHints(dpy,window,cli->wmHints)) {
- X cli->wmHints->flags = 0L;
- X }
- X
- X /*
- X * Get the protocols in which the client will participate
- X */
- X if (!PropGetWMProtocols(dpy,window,&(cli->protocols))) {
- X cli->protocols = 0;
- X }
- X
- X /*
- X * Figure out what focus mode this window intends
- X */
- X cli->focusMode = focusModeFromHintsProtocols(cli->wmHints,
- X cli->protocols);
- X
- X /*
- X * Get the window class and instance strings
- X */
- X if (!PropGetWMClass(dpy,window,&(cli->wmClass),&(cli->wmInstance))) {
- X cli->wmClass = cli->wmInstance = NULL;
- X }
- X
- X /*
- X * Get the OpenLook window type and associated decorations
- X */
- X cli->wmDecors = getOLWinDecors(dpy, window, transient, cli);
- X
- X /*
- X * Establish window groups. Policy: if the window is transient, this
- X * takes priority over any window group specified in WM_HINTS. If
- X * it's transient, make it be part of the window group of the window
- X * it is transient for. Otherwise, use the group specified in
- X * WM_HINTS. If no group is specified in WM_HINTS, consider the
- X * window to be the leader of its own group.
- X */
- X if (transient) {
- X winGeneric = WIGetInfo(cli->transientFor);
- X if (winGeneric != NULL)
- X cli->groupid = winGeneric->core.client->groupid;
- X else
- X cli->groupid = cli->transientFor;
- X } else if ((cli->wmHints) && (cli->wmHints->flags & WindowGroupHint)) {
- X cli->groupid = cli->wmHints->window_group;
- X } else {
- X cli->groupid = window;
- X }
- X
- X if (cli->groupid == window)
- X cli->groupmask = GROUP_LEADER;
- X else
- X {
- X if (((cli->wmDecors->flags & WMDecorationPushPin) &&
- X (cli->wmDecors->menu_type == MENU_LIMITED))
- X || transient)
- X {
- X cli->groupmask = GROUP_DEPENDENT;
- X }
- X else
- X {
- X cli->groupmask = GROUP_INDEPENDENT;
- X }
- X }
- X GroupAdd(cli->groupid,cli,cli->groupmask);
- X
- X /*
- X * Officially set up the frame
- X */
- X winFrame = MakeFrame(cli,window,&paneAttr);
- X
- X /*
- X * If the hints don't specify a location, we choose a suitable one,
- X * taking into account the window size and decoration sizes.
- X */
- X if ( !fexisting &&
- X !(normHints->flags & USPosition) &&
- X (!(normHints->flags & PPosition) ||
- X (GRV.PPositionCompat && paneAttr.x <= 1 && paneAttr.y <= 1)))
- X {
- X calcPosition(dpy, screen, &paneAttr, winFrame);
- X }
- X else if (!fexisting && (normHints->flags & USPosition) &&
- X !GRV.UseRelativePosition) {
- X paneAttr.x += cli->scrInfo->vdm->offsetX;
- X paneAttr.y += cli->scrInfo->vdm->offsetY;
- X }
- X
- X /*
- X * See if the position needs to be constrained to a logical
- X * screen due to entries in .olvwmrc
- X */
- X if (!XFetchName(dpy, window, &mc.name))
- X mc.name = NULL;
- X icon_x = icon_y = 0;
- X if (cli->groupmask != GROUP_DEPENDENT)
- X if (cli->wmHints)
- X if (cli->wmHints->flags & IconPositionHint)
- X SearchProgString(dpy, cli->scrInfo, mc.name,
- X cli->wmInstance, cli->wmClass,
- X &paneAttr.x, &paneAttr.y,
- X &cli->wmHints->icon_x, &cli->wmHints->icon_y);
- X else SearchProgString(dpy, cli->scrInfo, mc.name,
- X cli->wmInstance, cli->wmClass,
- X &paneAttr.x, &paneAttr.y,
- X &icon_x, &icon_y);
- X else SearchProgString(dpy, cli->scrInfo, mc.name, NULL, NULL,
- X &paneAttr.x, &paneAttr.y, &icon_x, &icon_y);
- X else {
- X /*
- X * Map the popup on the same screen as the group leader
- X */
- X Client *leader = GroupLeader(cli->groupid);
- X int curScreen;
- X int dw = DisplayWidth(dpy, screen);
- X int dh = DisplayHeight(dpy, screen);
- X
- X if (leader != NULL) {
- X curScreen = leader->framewin->core.x / dw;
- X if (leader->framewin->core.x < 0)
- X curScreen--;
- X if (paneAttr.x < 0)
- X paneAttr.x = dw + (paneAttr.x % dw) + (curScreen * dw);
- X else paneAttr.x = (paneAttr.x % dw) + (curScreen * dw);
- X curScreen = leader->framewin->core.y / dh;
- X if (leader->framewin->core.y < 0)
- X curScreen--;
- X if (paneAttr.y < 0)
- X paneAttr.y = dh + (paneAttr.y % dh) + (curScreen * dh);
- X else paneAttr.y = (paneAttr.y % dh) + (curScreen * dh);
- X }
- X }
- X
- X
- X /*
- X * If a non-olwm created window then create the pane for it
- X * Else if it is a pinned menu then call the creation callback
- X * so that it can fix up its pane
- X */
- X if (ourWinInfo == NULL) {
- X winPane = MakePane(cli,winFrame,window,&paneAttr);
- X } else {
- X winPane = ourWinInfo;
- X (WinClass(winPane)->core.createcallback)(ourWinInfo,cli,
- X winFrame);
- X }
- X
- X /*
- X * Officially set up the icon
- X */
- X winIcon = MakeIcon(cli,window,&paneAttr);
- X winIconPane = MakeIconPane(cli,winIcon,cli->wmHints,fexisting);
- X
- X /*
- X * Keep track of any subwindows that need colormap installation
- X */
- X TrackSubwindows(cli);
- X
- X /*
- X * Size and generally configure the frame window tree
- X */
- X FrameSetPosFromPane(winFrame,paneAttr.x,paneAttr.y);
- X WinCallConfig(dpy, winPane, NULL);
- X
- X /*
- X * Size and generally configure the icon window tree
- X */
- X WinCallConfig(dpy, winIconPane, NULL);
- X if (cli->wmHints != NULL && (cli->wmHints->flags & IconPositionHint))
- X IconSetPos(winIcon,cli->wmHints->icon_x,cli->wmHints->icon_y);
- X else
- X IconSetPos(winIcon,icon_x,icon_y);
- X WinCallConfig(dpy, winIcon, NULL);
- X
- X /*
- X * We manually move the icon pane window, since all the configuration
- X * has been done with the icon pane parented to root.
- X */
- X WinRootPos(winIconPane, &tmpx, &tmpy);
- X XMoveWindow(dpy, winIconPane->core.self, tmpx, tmpy);
- X
- X /*
- X * Set the sticky bit according to the sticky list. We check the
- X * window's group below (stickyness is inherited by group).
- X * sticky was set when the client was created; if this is a VDM
- X * then sticky will be set to true in the callback
- X */
- X mc.class = cli->wmClass;
- X mc.instance = cli->wmInstance;
- X if (ListApply(GRV.StickyList, matchInstClass, &mc) != NULL)
- X cli->sticky = True;
- X if (mc.name)
- X XFree(mc.name);
- X
- X /*
- X * Determine the proper initial state of the window.
- X * If the window already exists and there is a WM_STATE property
- X * then use the state that the last window manager left there,
- X * otherwise use WM_HINTS.
- X */
- X if (fexisting &&
- X PropGetWMState(dpy,winPane->core.self,&winState,&iconWin)) {
- X if (winState == IconicState)
- X initstate = IconicState;
- X else
- X initstate = NormalState;
- X } else {
- X /* For new windows, check the initial_state field of WM_HINTS. */
- X if (cli->wmHints && (cli->wmHints->flags & StateHint)
- X && (cli->wmHints->initial_state == IconicState))
- X initstate = IconicState;
- X else
- X initstate = NormalState;
- X }
- X
- X /*
- X * Don't allow the popup into iconic state if its leader is in normal
- X * state.
- X *
- X * Also set the sticky field of the client based on the leader
- X */
- X if (cli->groupmask == GROUP_DEPENDENT) {
- X Client *leader = GroupLeader(cli->groupid);
- X if (leader != NULL) {
- X if (leader->wmState == NormalState && initstate == IconicState)
- X initstate = NormalState;
- X cli->sticky = leader->sticky;
- X }
- X }
- X
- X if (cli->sticky)
- X MakeSticky(cli, True);
- X MakeVirtual(cli);
- X ClientProcessDragDropInterest(cli, PropertyNewValue);
- X
- X /*
- X * Put the window into the correct initial state
- X */
- X switch ( initstate ) {
- X case NormalState:
- X cli->wmState = NormalState;
- X MapRaised(winFrame);
- X XMapRaised(dpy, winPane->core.self);
- X if (!fexisting) {
- X FrameWarpPointer(cli);
- X if (GRV.AutoInputFocus)
- X ClientSetFocus(cli, True, CurrentTime);
- X if (GRV.AutoColorFocus)
- X LockColormap(dpy, cli, winPane);
- X }
- X break;
- X case IconicState:
- X cli->wmState = IconicState;
- X /* unmap the window in case it was mapped originally */
- X XUnmapWindow(dpy, winPane->core.self);
- X winPane->pcore.pendingUnmaps++;
- X /* dependent group followers don't get their own icons */
- X if (cli->groupmask != GROUP_DEPENDENT)
- X IconShow(cli, winIcon);
- X break;
- X }
- X ClientSetWMState(cli);
- X
- X /*
- X * Get the window state
- X */
- X ClientGetWindowState(cli);
- X
- X /*
- X * Turn off prop read filtering
- X */
- X PropClearAvailable();
- X
- X return cli;
- X}
- X
- X/*
- X * ReparentTree -- called at start up, this routine queries the window
- X * tree and reparents all the windows
- X */
- Xvoid
- XReparentTree(dpy,treeroot)
- XDisplay *dpy;
- XWindow treeroot;
- X{
- X unsigned int numChildren;
- X Window *children, root, parent, w;
- X int ii;
- X Client *cli;
- X
- X children = NULL;
- X
- X if (XQueryTree(dpy, treeroot, &root, &parent,
- X &children, &numChildren))
- X {
- X for (ii=0; ii<numChildren; ii++)
- X {
- X w = children[ii];
- X if (WIGetInfo(w) == NULL)
- X {
- X cli = StateNew(dpy, treeroot, w, True, NULL);
- X if (cli != NULL)
- X {
- X cli->framewin->fcore.panewin->pcore.pendingUnmaps++;
- X /* unmap because of reparent */
- X }
- X }
- X }
- X }
- X
- X if (children != NULL)
- X XFree((char *)children);
- X}
- X
- X
- X/*
- X * StateNormIcon - transition a window to IconicState from NormalState
- X */
- Xvoid
- XStateNormIcon(cli)
- XClient *cli;
- X{
- X WinIconFrame *winIcon = cli->iconwin;
- X
- X if (winIcon == NULL)
- X return;
- X
- X /* don't do some other transition */
- X if (cli->wmState != NormalState)
- X return;
- X
- X /* we can't iconify if we are a dependent */
- X if (cli->groupmask == GROUP_DEPENDENT)
- X return;
- X
- X /* Map the icon window */
- X IconShow(cli, winIcon);
- X
- X /* iconify self and dependents */
- X if (cli->groupmask == GROUP_LEADER)
- X GroupApply(cli->groupid, iconifyOne, winIcon,
- X GROUP_LEADER|GROUP_DEPENDENT);
- X else
- X iconifyOne(cli,winIcon);
- X
- X if (cli == CurrentClient && !GRV.FocusFollowsMouse)
- X ClientSetFocus(cli, False, TimeFresh(cli->iconwin));
- X}
- X
- X/*
- X * StateIconNorm - transition a window to NormalState from IconicState
- X */
- Xvoid
- XStateIconNorm(cli)
- XClient *cli;
- X{
- X WinIconFrame *winIcon = cli->iconwin;
- X
- X if (winIcon == NULL)
- X return;
- X
- X /* don't do some other transition */
- X if (cli->wmState != IconicState)
- X return;
- X
- X if (cli->groupmask == GROUP_LEADER)
- X deiconifyGroup(cli, winIcon);
- X else
- X deiconifyOne(cli,winIcon,True);
- X
- X /* Unmap icons */
- X IconHide(cli, winIcon);
- X
- X if (cli == CurrentClient && !GRV.FocusFollowsMouse)
- X ClientSetFocus(cli, True, TimeFresh(cli->framewin));
- X}
- X
- X/*
- X * StateWithdrawn - a window is being withdrawn; tear down all related
- X * structures; clear the client out of all lists it may be
- X * on; reparent the pane window
- X */
- Xvoid
- XStateWithdrawn(cli)
- XClient *cli;
- X{
- X WinIconFrame *iconInfo = cli->iconwin;
- X WinPaneFrame *frameInfo = cli->framewin;
- X WinPane *paneInfo;
- X Window pane;
- X Display *dpy = cli->dpy;
- X
- X if (iconInfo == NULL || frameInfo == NULL)
- X return;
- X
- X paneInfo = (WinPane*)(frameInfo->fcore.panewin);
- X pane = paneInfo->core.self;
- X iconInfo = cli->iconwin;
- X
- X /* Return the pointer if necessary */
- X FrameUnwarpPointer(cli);
- X
- X /* Unmap the frame and pane. */
- X UnmapWindow(frameInfo);
- X XUnmapWindow(dpy, pane);
- X
- X /* Unmap the icon */
- X if (iconInfo != NULL)
- X IconHide(cli, iconInfo);
- X
- X /* move the pane and unparent it */
- X FrameUnparentPane(cli, frameInfo, paneInfo);
- X
- X DestroyClient(cli);
- X}
- X
- X/************************************************************************
- X * Top-Level Window Property Update Functions
- X ************************************************************************/
- X
- X/*
- X * Refresh SizeHints from WM_NORMAL_HINTS property. The new values
- X * can simply be copied into the client's normHints.
- X */
- Xvoid
- XStateUpdateWMNormalHints(cli,event)
- X Client *cli;
- X XPropertyEvent *event;
- X{
- X Window pane;
- X XSizeHints sizeHints;
- X Bool preICCCM;
- X
- X if (event->state != PropertyNewValue)
- X return;
- X
- X pane = PANEWINOFCLIENT(cli);
- X
- X if (!PropGetWMNormalHints(cli->dpy,pane,&sizeHints,&preICCCM))
- X return;
- X
- X *(cli->normHints) = sizeHints;
- X}
- X
- X/*
- X * Reapply WMHints from the WM_HINTS property. Ignore everything but
- X * InputHint and Icon{Pixmap/Mask}Hint.
- X */
- Xvoid
- XStateUpdateWMHints(cli,event)
- X Client *cli;
- X XPropertyEvent *event;
- X{
- X Window pane;
- X XWMHints wmHints;
- X WinIconPane *iconPane;
- X Pixmap iconMask;
- X
- X if (cli->framewin == NULL || cli->iconwin == NULL ||
- X event->state != PropertyNewValue)
- X return;
- X
- X pane = PANEWINOFCLIENT(cli);
- X iconPane = (WinIconPane *)cli->iconwin->fcore.panewin;
- X
- X if (!PropGetWMHints(cli->dpy,pane,&wmHints))
- X return;
- X
- X if (wmHints.flags & InputHint) {
- X cli->focusMode =
- X focusModeFromHintsProtocols(&wmHints,cli->protocols);
- X }
- X
- X if (wmHints.flags & IconPixmapHint)
- X IconPaneSetPixmap(cli->dpy,iconPane,wmHints.icon_pixmap);
- X if (wmHints.flags & IconMaskHint)
- X IconPaneSetMask(cli->dpy,iconPane,wmHints.icon_mask);
- X if (wmHints.flags & IconPixmapHint || wmHints.flags & IconMaskHint)
- X WinDrawFunc(iconPane);
- X
- X if (cli->wmHints == NULL)
- X cli->wmHints = MemNew(XWMHints);
- X
- X *(cli->wmHints) = wmHints;
- X}
- X
- X/*
- X * Reset client protocols and focusMode from WM_PROTOCOLS
- X */
- Xvoid
- XStateUpdateWMProtocols(cli,event)
- X Client *cli;
- X XPropertyEvent *event;
- X{
- X Window pane;
- X int protocols;
- X
- X if (cli->framewin == NULL || event->state != PropertyNewValue)
- X return;
- X
- X pane = PANEWINOFCLIENT(cli);
- X
- X if (!PropGetWMProtocols(cli->dpy,pane,&protocols))
- X return;
- X
- X if (cli->protocols == protocols)
- X return;
- X
- X cli->focusMode = focusModeFromHintsProtocols(cli->wmHints,protocols);
- X cli->protocols = protocols;
- X}
- X
- X/*
- X * StateUpdateWinAttr - reread the _OL_WIN_ATTR property.
- X * For now just apply WA_PINSTATE.
- X */
- Xvoid
- XStateUpdateWinAttr(cli,event)
- X Client *cli;
- X XPropertyEvent *event;
- X{
- X OLWinAttr winAttr;
- X Bool old;
- X Window pane;
- X
- X if (cli->framewin == NULL || event->state != PropertyNewValue)
- X return;
- X
- X pane = PANEWINOFCLIENT(cli);
- X
- X if (!PropGetOLWinAttr(cli->dpy,pane,&winAttr,&old))
- X return;
- X
- X if ((winAttr.flags & WA_PINSTATE) && ClientIsPinnable(cli)) {
- X WinPushPin *pushPin = (WinPushPin *)cli->framewin->winDeco;
- X PushPinSetPinState(cli->dpy,pushPin,
- X winAttr.pin_initial_state,False);
- X }
- X}
- X
- X/*
- X * StateUpdateDecorAdd - read the DecorAdd property and reapply it
- X */
- Xvoid
- XStateUpdateDecorAdd(cli,event)
- X Client *cli;
- X XPropertyEvent *event;
- X{
- X /* REMIND - this needs to be implemented */
- X}
- X
- X/*
- X * StateUpdateDecorDel - read the DecorDel property and reapply it
- X */
- Xvoid
- XStateUpdateDecorDel(cli,event)
- X Client *cli;
- X XPropertyEvent *event;
- X{
- X /* REMIND - this needs to be implemented */
- X}
- END_OF_FILE
- if test 33415 -ne `wc -c <'states.c'`; then
- echo shar: \"'states.c'\" unpacked with wrong size!
- fi
- # end of 'states.c'
- fi
- echo shar: End of archive 10 \(of 21\).
- cp /dev/null ark10isdone
- MISSING=""
- for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 ; do
- if test ! -f ark${I}isdone ; then
- MISSING="${MISSING} ${I}"
- fi
- done
- if test "${MISSING}" = "" ; then
- echo You have unpacked all 21 archives.
- rm -f ark[1-9]isdone ark[1-9][0-9]isdone
- else
- echo You still need to unpack the following archives:
- echo " " ${MISSING}
- fi
- ## End of shell archive.
- exit 0
- --
- Molecular Simulations, Inc. mail: dcmartin@postgres.berkeley.edu
- 796 N. Pastoria Avenue uucp: uwvax!ucbvax!dcmartin
- Sunnyvale, California 94086 at&t: 408/522-9236
-